package dk.simonvogensen.itodo.shared.model;

import dk.simonvogensen.itodo.client.model.ProjectId;

import java.io.Serializable;
import java.util.*;

public class TagItem implements Serializable {

    private TodoItem todoItem;
    private String tag;
    private List<TagLine> tagLineList;

    public TagItem() {}

    public TagItem(TodoItem todoItem, String tag) {
        this.todoItem = todoItem;
        this.tag = tag;
        tagLineList = new ArrayList<TagLine>();
    }

    public TodoItem getTodoItem() {
        return todoItem;
    }

    public static Set<TagItem> getTagSet(Config config, List<TodoItem> itemList) {
        Set<TagItem> tagSet = new HashSet<TagItem>();
        for (TodoItem todoItem : itemList) {
            for (TagItem tagItem : todoItem.getTagItemList()) {
                if (ProjectId.contains(tagItem.getName(), config.getProjectIdList()) == null)
                    tagSet.add(tagItem);
            }
        }
        return tagSet;
    }

    public static List<TagItem> getAllTagItems(List<TodoItem> todoItemList) {
        List<TagItem> tagItemList = new ArrayList<TagItem>();
        for (TodoItem todoItem : todoItemList) {
            tagItemList.addAll(todoItem.getTagItemList());
        }
        return tagItemList;
    }

    public static Collection<TagItem> getAllTagItems(TodoItem todoItem) {
        Map<String, TagItem> tagItemMap = new HashMap<String, TagItem>();
        if(todoItem.getText() != null) {
            String[] lines = todoItem.getText().split("\n");
            for (int i = 0; i < lines.length; i++) {
                if (lines[i].matches("- \\w*")) {
                    TagItem tagItem = tagItemMap.get(lines[i]);
                    if(tagItem == null) tagItem = new TagItem(todoItem, lines[i]);

                    while (++i < lines.length && !lines[i].trim().equals("") && !lines[i].matches("-\\s.*")) {
                        if (lines[i].matches("\\s\\s-\\s.*")) {
                            tagItem.tagLineList.add(new TagLine(tagItem, lines[i]));
                        }
                    }
                    // only add tagitem if it contains lines
                    if(!tagItem.getTagLineList().isEmpty()) tagItemMap.put(tagItem.getName(), tagItem);
                }
            }
        }
        return tagItemMap.values();
    }

    public String getName() {
        return tag;
    }

    public List<TagLine> getTagLineList() {
        return tagLineList;
    }

    public static List<TagLine> getTagLines(List<String> activeTagList, int maxNumberOfTagLines, List<TodoItem> todoItemList) {
        List<TagLine> tagLineList = new ArrayList<TagLine>();
        outer: for (TodoItem todoItem : todoItemList) {
            for (TagItem tagItem : todoItem.getTagItemList()) {
                if(activeTagList.contains(tagItem.getName())) {
                    for (TagLine tagLine : tagItem.getTagLineList()) {
                        tagLineList.add(tagLine);
                        if(tagLineList.size() == maxNumberOfTagLines) break outer;
                    }
                }
            }
        }
        return tagLineList;
    }

    public static int getTagLineCount(List<String> activeTagList, List<TodoItem> todoItemList) {
        int tagLineCount = 0;
        for (TodoItem todoItem : todoItemList) {
            for (TagItem tagItem : todoItem.getTagItemList()) {
                if(activeTagList.contains(tagItem.getName())) {
                    tagLineCount += tagItem.getTagLineList().size();
                }
            }
        }
        return tagLineCount;
    }
}
